
package com.zdkj.subway.stm.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zdkj.common.core.constant.CommonConstants;
import com.zdkj.common.security.service.PigxUser;
import com.zdkj.common.security.util.ObjectUtils;
import com.zdkj.common.security.util.SecurityUtils;
import com.zdkj.subway.stm.constant.StmTableCommon;
import com.zdkj.subway.stm.dto.out.SwStHandworkCleanRecordDTO;
import com.zdkj.subway.stm.entity.*;
import com.zdkj.subway.stm.mapper.SwStHandworkCleanRecordMapper;
import com.zdkj.subway.stm.service.SwStHandworkCleanRecordDetailsService;
import com.zdkj.subway.stm.service.SwStHandworkCleanRecordService;
import com.zdkj.subway.stm.service.SwStmStationDataEntryLogService;
import com.zdkj.subway.stm.util.BeanUtilsStm;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 手工清出数据 主表
 * @author songtuo
 * @date 2020-07-07 18:08:07
 */
@Service
@AllArgsConstructor
public class SwStHandworkCleanRecordServiceImpl extends ServiceImpl<SwStHandworkCleanRecordMapper, SwStHandworkCleanRecord> implements SwStHandworkCleanRecordService {
    @Autowired
    SwStHandworkCleanRecordDetailsService detailsService;
    private final SwStmStationDataEntryLogService swStmStationDataEntryLogService;

    @Override
    @Transactional
    public boolean saveSwStHandworkCleanRecord(SwStHandworkCleanRecordDTO swStHandworkCleanRecordDTO) {
        //1:获取公共属性
        SwStHandworkCleanRecord swStHandworkCleanRecord = swStHandworkCleanRecordDTO.getSwStHandworkCleanRecord();
        SwStHandworkCleanRecord swStHandworkCleanRecordObj = ObjectUtils.getDefaultObj(SwStHandworkCleanRecord.class);
        BeanUtil.copyProperties(swStHandworkCleanRecordObj, swStHandworkCleanRecord, CopyOptions.create().setIgnoreNullValue(true));
        List<SwStHandworkCleanRecordDetails> details = swStHandworkCleanRecordDTO.getDetails();
        BeanUtilsStm.buildProperties(details);
        if (CollectionUtil.isEmpty(details)) {
            return false;
        }
        //2:统计主表的金钱数
        countAmount(swStHandworkCleanRecord, details);
        //3：保存主表
		//3.1.设置主表的更新人编号和名称，为报表差错做准备
		PigxUser user = SecurityUtils.getUser();           
        swStHandworkCleanRecord.setEntryUpdateJobNo(user.getUserCode());
		swStHandworkCleanRecord.setEntryUpdateJobName(user.getNikeName());	

        swStHandworkCleanRecord.setApprovalStatus("0");
        save(swStHandworkCleanRecord);
        //4: 保存从表
        details.forEach(x -> x.setRelationId(swStHandworkCleanRecord.getId()));
        detailsService.saveBatch(details);
        return true;
    }

    /**
     * 统计 主表的总钱数
     *
     * @param swStHandworkCleanRecord
     * @param details
     */
    private void countAmount(SwStHandworkCleanRecord swStHandworkCleanRecord, List<SwStHandworkCleanRecordDetails> details) {
        Double totalCleanCoinAmount = 0d;
        Double totalCleanPaperAmount = 0d;
        for (SwStHandworkCleanRecordDetails detail : details) {
            BigDecimal clearOutAmount = detail.getClearOutAmount();
            BigDecimal clearOutPaperAmount = detail.getClearOutPaperAmount();
            totalCleanCoinAmount += clearOutAmount.doubleValue();
            totalCleanPaperAmount += clearOutPaperAmount.doubleValue();
            /*if ("1".equals(detail.getTvmCashBoxType()) || "2".equals(detail.getTvmCashBoxType())) {
                totalCleanCoinAmount += clearOutAmount.doubleValue();
            }
            if ("3".equals(detail.getTvmCashBoxType()) || "4".equals(detail.getTvmCashBoxType()) || "5".equals(detail.getTvmCashBoxType())) {
                totalCleanPaperAmount += clearOutAmount.doubleValue();
            }*/
        }
        Double totalCleanAmount = totalCleanCoinAmount + totalCleanPaperAmount;
        swStHandworkCleanRecord.setTotalCleanCoinAmount(new BigDecimal(totalCleanCoinAmount));
        swStHandworkCleanRecord.setTotalCleanPaperAmount(new BigDecimal(totalCleanPaperAmount));
        swStHandworkCleanRecord.setTotalCleanAmount(new BigDecimal(totalCleanAmount));
    }

    @Override
    @Transactional
    public boolean updateSwStHandworkCleanRecord(SwStHandworkCleanRecordDTO swStHandworkCleanRecordDTO) {
        List<SwStHandworkCleanRecordDetails> details = swStHandworkCleanRecordDTO.getDetails();
        SwStHandworkCleanRecord swStHandworkCleanRecord = swStHandworkCleanRecordDTO.getSwStHandworkCleanRecord();
        Integer id = swStHandworkCleanRecord.getId();

        //修改之前添加记录表（先添加主表）
        SwStHandworkCleanRecord cleanRecord = getById(id);
        if("1".equals(cleanRecord.getReportModifyStatus()) && cleanRecord != null) {
            //List<SwStmStationDataEntryLog> list = new ArrayList<>();
            PigxUser user = SecurityUtils.getUser();
            cleanRecord.setEntryUpdateJobNo(user.getUserCode());
            cleanRecord.setEntryUpdateJobName(user.getNikeName());
            cleanRecord.setEntryUpdateTime(new Date());
            SwStmStationDataEntryLog swStmStationDataEntryLog = new SwStmStationDataEntryLog();
            swStmStationDataEntryLog.setRelationId(cleanRecord.getId());
            swStmStationDataEntryLog.setLogTableName(StmTableCommon.SW_ST_HANDWORK_CLEAN_RECORD);
            swStmStationDataEntryLog.setLogInfo(JSONObject.toJSONString(cleanRecord));
            swStmStationDataEntryLog.setUpdateJobNo(user.getUserCode());
            swStmStationDataEntryLog.setUpdateJobName(user.getNikeName());
            swStmStationDataEntryLog.setUpdateTime(new Date());
            //list.add(swStmStationDataEntryLog);
            swStmStationDataEntryLogService.save(swStmStationDataEntryLog);

            //修改之前添加记录表（再添加子表）
            List<SwStmStationDataEntryLog> list = new ArrayList<>();
            List<SwStHandworkCleanRecordDetails> swStHandworkCleanRecordDetails = detailsService.list(
                    Wrappers.<SwStHandworkCleanRecordDetails>lambdaQuery()
                            .eq(SwStHandworkCleanRecordDetails::getRelationId, cleanRecord.getId())
                            //.eq(SwStHandworkCleanRecordDetails::getReportModifyStatus, "1")
                            .eq(SwStHandworkCleanRecordDetails::getDelFlag,0));

            if(CollectionUtil.isNotEmpty(swStHandworkCleanRecordDetails)){
                swStHandworkCleanRecordDetails.stream().forEach(recordDetails -> {
                    recordDetails.setEntryUpdateJobNo(user.getUserCode());
                    recordDetails.setEntryUpdateJobName(user.getNikeName());
                    recordDetails.setEntryUpdateTime(new Date());

                    SwStmStationDataEntryLog swStmStationDataEntryLogChild = new SwStmStationDataEntryLog();
                    swStmStationDataEntryLogChild.setRelationId(cleanRecord.getId());
                    swStmStationDataEntryLogChild.setLogTableName(StmTableCommon.SW_ST_HANDWORK_CLEAN_RECORD_DETAILS);
                    swStmStationDataEntryLogChild.setMainId(swStmStationDataEntryLog.getId());//记录表id
                    swStmStationDataEntryLogChild.setLogInfo(JSONObject.toJSONString(recordDetails));
                    swStmStationDataEntryLogChild.setUpdateJobNo(user.getUserCode());
                    swStmStationDataEntryLogChild.setUpdateJobName(user.getNikeName());
                    swStmStationDataEntryLogChild.setUpdateTime(new Date());
                    list.add(swStmStationDataEntryLogChild);
                });
            }
            swStmStationDataEntryLogService.saveBatch(list);
        }


        //1:统计金钱数
        countAmount(swStHandworkCleanRecord, details);
        //2:更新主表
		//2.1.设置主表的更新人编号和名称，为报表差错做准备
		PigxUser user = SecurityUtils.getUser();           
        swStHandworkCleanRecord.setEntryUpdateJobNo(user.getUserCode());
		swStHandworkCleanRecord.setEntryUpdateJobName(user.getNikeName());	
        updateById(swStHandworkCleanRecord);
        //3:更新从表  需要注意点是 从表是有可能有新增数据的
        List<SwStHandworkCleanRecordDetails> updateData = new ArrayList<>();
        List<SwStHandworkCleanRecordDetails> insertData = new ArrayList<>();
        //4： 将新增的数据统计出来
        for (SwStHandworkCleanRecordDetails detail : details) {
            if (detail.getId() != null) {
                updateData.add(detail);
            } else {
                detail.setRelationId(id);
                insertData.add(detail);
            }
        }
        //5: 删除已经在界面删除的数据
        List<Integer> updateIds = updateData.stream().map(x -> x.getId()).collect(Collectors.toList());
        List<SwStHandworkCleanRecordDetails> orginRemoveList = new ArrayList<>();
        List<SwStHandworkCleanRecordDetails> originSunDeatails = detailsService.list(new QueryWrapper<SwStHandworkCleanRecordDetails>().eq("RELATION_ID", id));
        for (SwStHandworkCleanRecordDetails originSunDeatail : originSunDeatails) {
            if (!updateIds.contains(originSunDeatail.getId())) {
                orginRemoveList.add(originSunDeatail);
            }
        }
        //7: 移除本次删除的数据
        if (CollectionUtil.isNotEmpty(orginRemoveList)) {
            orginRemoveList.forEach(x -> x.setDelFlag(CommonConstants.STATUS_DEL));
            detailsService.updateBatchById(orginRemoveList);
        }
        //8: 更新本次修改的数据
        if (CollectionUtil.isNotEmpty(updateData)) {
            detailsService.updateBatchById(updateData);
        }
        //9: 新增本次添加的数据
        if (CollectionUtil.isNotEmpty(insertData)) {
            insertData.forEach(x -> x.setRelationId(id));
            detailsService.saveBatch(insertData);
        }
        return true;
    }

    @Override
    @Transactional
    public boolean deleteCascadeById(Integer id) {
        //删除主表
        removeById(id);
        List<SwStHandworkCleanRecordDetails> originSunDeatails = detailsService.list(new QueryWrapper<SwStHandworkCleanRecordDetails>().eq("RELATION_ID", id));
        //不用判断空 在插入的时候已经判断了
        originSunDeatails.forEach(x -> x.setDelFlag(CommonConstants.STATUS_DEL));
        detailsService.updateBatchById(originSunDeatails);
        return true;
    }

    @Override
    @Transactional
    public SwStHandworkCleanRecordDTO queryDetailsByid(Integer id) {
        SwStHandworkCleanRecordDTO stHandworkCleanRecordDTO = new SwStHandworkCleanRecordDTO();
        SwStHandworkCleanRecord swStHandworkCleanRecord = getById(id);
        List<SwStHandworkCleanRecordDetails> originSunDeatails = detailsService.list(new QueryWrapper<SwStHandworkCleanRecordDetails>().eq("RELATION_ID", id).eq("DEL_FLAG", 0));
        stHandworkCleanRecordDTO.setDetails(originSunDeatails);
        stHandworkCleanRecordDTO.setSwStHandworkCleanRecord(swStHandworkCleanRecord);
        return stHandworkCleanRecordDTO;
    }
}
